<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>第一个webGL页面</title>

</head>
<body>
    <canvas id="canvas" width = "400" height = "400"></canvas>
</body>
<script src="../lib/webgl-utils2.js"></script>
<script id="2d-vertex-shader" type="x-shader/x-vertex">
        // attribute : 是glsl中三种变量声明之一，代表的是与顶点相关的数据，只能用在顶点着色器中。这个变量存储了从外部传输进顶点着色器的数据。
        attribute vec2 a_position;
        // 顶点着色器的内置变量
        // gl_Position : 位置
        // gl_PointSize : 大小
        // 脚本的入口方法 main()
        void main() {
            gl_Position = vec4(a_position, 0, 1);
        }
    </script>
<script id="2d-fragment-shader" type="x-shader/x-fragment">
        //uniform : 是glsl中另外一种变量声明，表示的是JavaScript程序向顶点着色器和片元着色器传输的一致的(不变的)数据；也就是是说这种变量既可以用在顶点着色器也可以用于片元着色器。
        uniform vec4 u_FragColor;
        // 片区着色器内置变量
        // gl_FragColor : 颜色，按照三原色输入相应数字，构成相应颜色
        void main() {
            gl_FragColor = vec4(0, 1, 0, 1);  // green
        }
    </script>

<!-- varying ：是glsl的第三种声明变量，它表示的是从顶点着色器流向片元着色器可变的变量 -->
</html>
<script>
    // Get A WebGL context 获取一个上下文
    var canvas = document.getElementById("canvas");
    var gl = canvas.getContext("experimental-webgl");

    // setup a GLSL program 设置一个着色器描述语言 即设置顶点着色器，片元着色器
    var program = createProgramFromScripts(gl, ["2d-vertex-shader", "2d-fragment-shader"]);
    gl.useProgram(program);

    // look up where the vertex data needs to go.  查找顶点数据需要去的地方
    var positionLocation = gl.getAttribLocation(program, "a_position");

    // Create a buffer and put a single clipspace rectangle in 创建一个缓冲区，并在其中放置一个剪贴空间矩形
    // it (2 triangles) 两个三角形
    var buffer = gl.createBuffer();
    //ARRAY_BUFFER 阵列缓冲区
    gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
    gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array([
            -1.0, -1.0,
            1.0, -1.0,
            -1.0,  1.0,
            -1.0,  1.0,
            1.0, -1.0,
            1.0,  1.0]),
        gl.STATIC_DRAW);
    //enableVertexAttribArray 启用顶点属性索引：在指定的索引处将通用顶点属性数组打开到属性数组列表中。
    gl.enableVertexAttribArray(positionLocation);
    //vertexAttribPointer: 告诉显卡从当前绑定的缓冲区（bindBuffer()指定的缓冲区）中读取顶点数据,
    // 第一个参数 使用那个变量来接受 缓冲区的值
    // 第二个参数GLint size是指的维度, 指定缓冲区中每个顶点的分量个数（1到4）。若size的值比 attribute变量需要的分量个数少，则执行补全规则。
    // 第三个参数GLenum type是指参数类型，包括gl.INT,gl.FLOAT,gl.SHORT等等多种。
    // 第四个参数GLboolean normalized 是指是否将非浮点型的数据规划到[0,1]或者[-1,1]区间，
    // 第五个参数GLsizei stride， 相邻两个顶点间字节数，默认为0
    // 第六个参数GLintptr offset，绑定的缓冲区偏移offset个字节开始读数据，默认为0，这里offset=0,指从绑定缓冲区首地址开始读。
    gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);

    // draw drawArrays()
    // 第一个参数GLenum mode指的是绘制图元模式，下面是WebGL的图元模式
    // 参考：https://blog.csdn.net/liujianxun111/article/details/79010938
    // GLenum POINTS         单独的将顶点画出来
    // GLenum LINES          单独地将直线画出来
    // GLenum LINE_LOOP      连贯地将直线画出来。行为和 GL_LINE_STRIP 类似，但是会自动将最后一个顶点和第一个顶点通过直线连接起来
    // GLenum LINE_STRIP     连贯地将直线画出来
    // GLenum TRIANGLES      这个参数意味着OpenGL使用三个顶点来组成图形。所以，在开始的三个顶点，将用顶点1，顶点2，顶点3来组成一个三角形。完成后，在用下一组的三个顶点(顶点4，5，6)来组成三角形，直到数组结束。
    // GLenum TRIANGLE_STRIP   OpenGL的使用将最开始的两个顶点出发，然后遍历每个顶点，这些顶点将使用前2个顶点一起组成一个三角形。
    // GLenum TRIANGLE_FAN     在跳过开始的2个顶点，然后遍历每个顶点，让OpenGL将这些顶点于它们前一个，以及数组的第一个顶点一起组成一个三角形。
    // 第二个参数GLint first指从绑定的缓冲区（bindBuffer()）中首地址偏移first 下标（不是字节数）开始读数据。
    // 第三个参数count是指绘制顶点数据的个数，即shader代码运行的次数。
    // gl.drawArrays(gl.LINE_LOOP, 0, 6);
    gl.drawArrays(gl.TRIANGLES, 0, 6);
</script>

